﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MediaStockService.cs" company="DST Nexdox">
//   Copyright (c) DST Nexdox. All rights reserved.
// </copyright>
// <summary>
//   Defines the MediaStockService type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Services
{
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Threading.Tasks;

  using DocProcessingRepository.Interfaces;

  using Entities;

  using Exceptions;

  using ServiceInterfaces;

  public class MediaStockService : IMediaStockService
  {
    private readonly IMediaStockRepository mediaStockRepository;

    private readonly IUserService userService;

    private readonly IMediaDefinitionAuditService mediaDefinitionAuditService;

    public MediaStockService(IMediaStockRepository mediaStockRepository, IUserService userService, IMediaDefinitionAuditService mediaDefinitionAuditService)
    {
      this.mediaStockRepository = mediaStockRepository;
      this.userService = userService;
      this.mediaDefinitionAuditService = mediaDefinitionAuditService;
    }

    public MediaStockEntity GetById(Int32 mediaStockId)
    {
      try
      {
        return this.mediaStockRepository.GetById(mediaStockId);
      }
      catch (Exception e)
      {
        throw new DocProcessingException("Unable to get media stock by Id", e);
      }
    }

    public List<MediaStockEntity> GetByMediaDefinition(Int32 mediaDefinitionId)
    {
      try
      {
        return this.mediaStockRepository.GetByMediaDefinition(mediaDefinitionId);
      }
      catch (Exception e)
      {
        throw new DocProcessingException("Unable to get media stock for media definition", e);
      }
    }

    public void UpdateStationNumbers(Int32 mediaDefinitionId, List<StationNumberAssignment> assignments)
    {
      try
      {
        if (!assignments.Any())
        {
          return;
        }

        ApplicationUser user = this.userService.GetApplicationUser();

        var messageLines = new List<String>();

        foreach (StationNumberAssignment assignment in assignments)
        {
          this.mediaStockRepository.UpdateStationNumber(assignment.MediaStockID, assignment.StationNumber);

          messageLines.Add(
            String.Format(
              "Media stock {0} [{1}:'{2}'] station number updated to {3}",
              assignment.StockId,
              assignment.Code,
              assignment.Description,
              assignment.StationNumber));
        }

        String message = String.Join(Environment.NewLine, messageLines);

        this.mediaDefinitionAuditService.AddAudit(
          mediaDefinitionId,
          user.Id,
          MediaDefinitionAudit.MediaDefinitionAuditType.MediaStockStationNumbersUpdated,
          DateTime.Now,
          message);
      }
      catch (Exception e)
      {
        throw new DocProcessingException("Unable to update station numbers", e);
      }
    }

    public void RemoveMediaStock(Int32 mediaStockId)
    {
      try
      {
        MediaStockEntity mediaStockToDelete = this.mediaStockRepository.GetById(mediaStockId);

        this.mediaStockRepository.DeleteMediaStock(mediaStockId);
        
        ApplicationUser user = this.userService.GetApplicationUser();
        this.mediaDefinitionAuditService.AddAudit(
          mediaStockToDelete.MediaDefId,
          user.Id,
          MediaDefinitionAudit.MediaDefinitionAuditType.MediaStockRemoved,
          DateTime.Now,
          String.Format("Media stock {0} [{1}:'{2}'] removed", mediaStockToDelete.StockId, mediaStockToDelete.Code, mediaStockToDelete.Description));
      }
      catch (Exception e)
      {
        throw new DocProcessingException("Unable to remove media stock", e);
      }
    }

    public MediaStockEntity AddMediaStock(Int32 stockId, Int32 mediaDefinitionId, Int32 stationNumber)
    {
      try
      {
        MediaStockEntity addedStock = this.mediaStockRepository.AddMediaStock(stockId, mediaDefinitionId, stationNumber);

        ApplicationUser user = this.userService.GetApplicationUser();

        String auditMessage = String.Format(
          "Media stock {0} [{1}:'{2}'] added with station number {3}",
          addedStock.StockId,
          addedStock.Code,
          addedStock.Description,
          stationNumber);

        this.mediaDefinitionAuditService.AddAudit(
          mediaDefinitionId,
          user.Id,
          MediaDefinitionAudit.MediaDefinitionAuditType.MediaStockAdded,
          DateTime.Now,
          auditMessage);

        return addedStock;
      }
      catch (Exception e)
      {
        throw new DocProcessingException("Unable to add media stock", e);
      }
    }
  }
}
